﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Collections.Generic;


namespace Xceed.Silverlight.Data
{
  internal class DataSourceEnumeratorWrapper
  {
    internal DataSourceEnumeratorWrapper( ISyncDataSourceEnumerator dataSourceEnumerator )
    {
      if( dataSourceEnumerator == null )
        throw new ArgumentNullException( "dataSourceEnumerator" );

      m_dataSourceEnumerator = dataSourceEnumerator;
    }

    public event EventHandler<IndexChangedEventArgs> IndexChanged
    {
      add
      {
        m_dataSourceEnumerator.IndexChanged += value;
      }
      remove
      {
        m_dataSourceEnumerator.IndexChanged -= value;
      }
    }

    public event EventHandler ItemCountChanged
    {
      add
      {
        m_dataSourceEnumerator.ItemCountChanged += value;
      }
      remove
      {
        m_dataSourceEnumerator.ItemCountChanged -= value;
      }
    }

    public event EventHandler HasPendingRequestsChanged
    {
      add
      {
        m_dataSourceEnumerator.HasPendingRequestsChanged += value;
      }
      remove
      {
        m_dataSourceEnumerator.HasPendingRequestsChanged -= value;
      }
    }

    public event EventHandler<DataChangedEventArgs> DataChanged
    {
      add
      {
        m_dataSourceEnumerator.DataChanged += value;
      }
      remove
      {
        m_dataSourceEnumerator.DataChanged -= value;
      }
    }

    public bool IsCachingEnumerator
    {
      get
      {
        return m_dataSourceEnumerator is ICachingEnumerator;
      }
    }

    public long Index
    {
      get
      {
        return m_dataSourceEnumerator.Index;
      }
    }

    public long ItemCount
    {
      get
      {
        return m_dataSourceEnumerator.ItemCount;
      }
    }

    public bool HasPendingRequests
    {
      get
      {
        return m_dataSourceEnumerator.HasPendingRequests;
      }
    }

    public DataPath Current
    {
      get
      {
        return m_dataSourceEnumerator.Current;
      }
    }

    public bool IsFirst( DataPath path, int levelDepth )
    {
      return m_dataSourceEnumerator.IsFirst( path, levelDepth );
    }

    public bool Move( bool approximateMove, long expectedMoveCount )
    {
      return m_dataSourceEnumerator.Move( approximateMove, expectedMoveCount );
    }

    public bool Move( long expectedMoveCount )
    {
      return m_dataSourceEnumerator.Move( expectedMoveCount );
    }

    public bool MoveAndFetch(
      long expectedMoveCount,
      int expectedFetchCount,
      out ICollection<DataPath> fetchedItems )
    {
      return m_dataSourceEnumerator.MoveAndFetch(
        expectedMoveCount,
        expectedFetchCount,
        out fetchedItems );
    }

    public bool MoveAndFetch(
      bool approximateMove,
      long expectedMoveCount,
      int expectedFetchCount,
      out ICollection<DataPath> fetchedItems )
    {
      return m_dataSourceEnumerator.MoveAndFetch(
        approximateMove,
        expectedMoveCount,
        expectedFetchCount,
        out fetchedItems );
    }


    public bool MoveNext()
    {
      return m_dataSourceEnumerator.MoveNext();
    }

    public bool MoveToHome()
    {
      return m_dataSourceEnumerator.MoveToHome();
    }

    public bool MoveToEnd()
    {
      return m_dataSourceEnumerator.MoveToEnd();
    }

    public void SetCacheSize( int size )
    {
      ICachingEnumerator cachingEnumerator = m_dataSourceEnumerator as ICachingEnumerator;

      if( cachingEnumerator == null )
        throw new InvalidOperationException( "An attempt was made to use an enumerator that does not support caching." );

      cachingEnumerator.SetCacheSize( size );
    }

    public void SetCacheSize( int size, double topTrimRatio )
    {
      ICachingEnumerator cachingEnumerator = m_dataSourceEnumerator as ICachingEnumerator;

      if( cachingEnumerator == null )
        throw new InvalidOperationException( "An attempt was made to use an enumerator that does not support caching." );

      cachingEnumerator.SetCacheSize( size, topTrimRatio );
    }

    public void Reset()
    {
      m_dataSourceEnumerator.Reset();
    }

    public bool JumpMoveAndFetch(
      SourcePosition startPosition,
      long expectedMoveCount,
      int expectedFetchCount,
      out ICollection<DataPath> fetchedItems )
    {
      JumpMoveAndFetchParameters parameters = new JumpMoveAndFetchParameters(
                                                    startPosition,
                                                    expectedMoveCount,
                                                    expectedFetchCount );
      Nullable<long> actualMoveCount;
      SourcePosition endPosition;
      RelativeOffset endPositionOffset;
      EstimateInt64 totalCount;

      return m_dataSourceEnumerator.JumpMoveAndFetch(
               parameters,
               out actualMoveCount,
               out fetchedItems,
               out endPosition,
               out endPositionOffset,
               out totalCount );
    }

    public bool JumpMoveAndFetch(
      DataPath startItem,
      long expectedMoveCount,
      int expectedFetchCount,
      out ICollection<DataPath> fetchedItems )
    {
      return m_dataSourceEnumerator.JumpMoveAndFetch(
               startItem,
               expectedMoveCount,
               expectedFetchCount,
               out fetchedItems );
    }

    public MoveAndFetchResult<DataPath> JumpMoveAndFetch(
      DataPath startItem,
      long expectedMoveCount,
      int expectedFetchCount )
    {

      JumpMoveAndFetchParameters parameters = new JumpMoveAndFetchParameters(
                                                new ItemPosition( startItem ),
                                                expectedMoveCount,
                                                expectedFetchCount );

      SourcePosition endPosition;
      Nullable<long> actualMoveCount;
      RelativeOffset endPositionOffset;
      EstimateInt64 totalCount;
      ICollection<DataPath> fetchedItems;

      bool result = m_dataSourceEnumerator.JumpMoveAndFetch(
               parameters,
               out actualMoveCount,
               out fetchedItems,
               out endPosition,
               out endPositionOffset,
               out totalCount );

      return new MoveAndFetchResult<DataPath>( actualMoveCount, fetchedItems, false, expectedMoveCount, expectedFetchCount, result, endPositionOffset, totalCount );
    }


    public GroupFetchResult FetchGroup( DataPath groupPath, GroupTarget groupTarget, int expectedFetchCount )
    {
      return m_dataSourceEnumerator.FetchGroup( groupPath, groupTarget, expectedFetchCount );
    }

    internal StatResults GetStatValues( StatParameters statParameter )
    {
      return m_dataSourceEnumerator.GetStatValues( statParameter );
    }

    #region Private Fields

    private ISyncDataSourceEnumerator m_dataSourceEnumerator; //null

    #endregion Private Fields
  }
}
